package com.zz.common.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;

public abstract class ImageUtil {
	
	public static Bitmap decodeStream(InputStream is){
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		
		BitmapFactory.decodeStream(is);
		long temp = opts.outHeight * opts.outWidth;
		if(temp >= 1280 * 768) {
			opts.inSampleSize = 3;
		} else if(temp >= 480 * 800) {
			opts.inSampleSize = 2;
		}
		
		Bitmap bitmap =null;
		try {
			bitmap = BitmapFactory.decodeStream(is);
		} catch(Throwable t) {
			t = null;
			bitmap = null;
		}
		
		return bitmap;
	}
	
	public static Bitmap decodeLocalFile(String localpath, int len){
		java.io.File localFile = new java.io.File(localpath);
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inSampleSize = 1;
		if (localFile.length()>=100*1024) {
			if (len == 240 || len == 320) {
				opts.inSampleSize = 2;
			}else {
				opts.inSampleSize = 1;
			}
		}
		if (localFile.length()>=200*1024) {
			if (len == 240 || len == 320) {
				opts.inSampleSize = 3;
			}else {
				opts.inSampleSize = 1;
			}
		}
		if (localFile.length()>=400*1024) {
			if (len == 240|| len == 320) {
				opts.inSampleSize = 4;
			}else {
				opts.inSampleSize = 2;
			}
		}
		if (localFile.length()>=500*1024) {
			if (len == 240 || len == 320) {
				opts.inSampleSize = 6;
			}else {
				opts.inSampleSize = 4;
			}
		}
		opts.inPreferredConfig = Bitmap.Config.RGB_565;
		opts.inPurgeable = true;    
		opts.inInputShareable = true; 
		Bitmap bitmap = null;
		
		try {
			bitmap = BitmapFactory.decodeFile(localpath, opts);
		} catch (Throwable t) {
		}
		return bitmap;
	}
    
	public static void saveBitmapToFile(Bitmap bitmap, File file) throws IOException {
		String parentPath = file.getParent();
		File parentFile = new File(parentPath);
		if(!parentFile.exists() || !parentFile.isDirectory()) {
			parentFile.mkdirs();
			parentFile = null;
		}
       	if(!file.exists() || !file.isFile()) {
       		file.createNewFile();
       	}
        FileOutputStream fOut = null;
        try {
        	fOut = new FileOutputStream(file);
        	bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
        	fOut.flush();
        } catch (IOException e) {
        } finally {
        	if(null != fOut) {
        		fOut.close();
        	}
        }
	}
	
	public static void saveBitmapFileAsJPEG(Bitmap bitmap, File file) throws IOException{
		String parentPath = file.getParent();
		File parentFile = new File(parentPath);
		if(!parentFile.exists() || !parentFile.isDirectory()) {
			parentFile.mkdirs();
			parentFile = null;
		}
       	if(!file.exists() || !file.isFile()) {
       		file.createNewFile();
       	}
        FileOutputStream fOut = null;
        try {
        	fOut = new FileOutputStream(file);
        	bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        	fOut.flush();
        } catch (IOException e) {
        } finally {
        	if(null != fOut) {
        		fOut.close();
        	}
        }
	}
	

    public static final Bitmap round(Bitmap src, float corner) {
    	if(null == src) {
    		return null;
    	}
    	
    	Bitmap output = null;
        try {
        	output = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Config.ARGB_8888);
        }
        catch(OutOfMemoryError oome) {
        }
        
        if(output != null) {
	        Canvas canvas = new Canvas(output);
	        Paint paint = new Paint();
	        final Rect rect = new Rect(0, 0, src.getWidth(), src.getHeight());
	        final RectF rectF = new RectF(rect);
	        final float roundPx = corner;
	        paint.setAntiAlias(true);
	        
	        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
	        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
	        canvas.drawBitmap(src, rect, rect, paint);
        }
        return output;
    }

    public static final void roundInCanvas(Bitmap src, Canvas outCanvas, int x, int y
    		, float corner, int bgColor) {
    	if(null == src || null == outCanvas) {
    		return;
    	}
    	
    	int imageWidth = src.getWidth();
    	int imageHeight = src.getHeight();
        
		
		final Rect dstRect = new Rect(x, y, imageWidth+x, imageHeight+y);
		final Rect srcRect = new Rect(0, 0, imageWidth, imageHeight);
		final RectF rectF = new RectF(srcRect);
		final float roundPx = corner;
		
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(bgColor);
		
		Bitmap mask = Bitmap.createBitmap(imageWidth, imageHeight, Config.ARGB_8888);
		Canvas maskCanvas = new Canvas(mask);
		maskCanvas.drawRoundRect(rectF, roundPx, roundPx, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		maskCanvas.drawBitmap(src, srcRect, srcRect, paint);
		  
		outCanvas.drawBitmap(mask, srcRect, dstRect, null);
    }
   
    public static BitmapFactory.Options getImageOptions(InputStream in) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in, null, opts);
        return opts;
    }

    public static Bitmap zoomIn(Bitmap bitmap, int maxW, int maxH) {

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        if (width <= maxW && height <= maxH)
            return bitmap;
        Matrix matrix = new Matrix(); 
        float ratio = (float) getRatio(width, height, maxW, maxH);
        matrix.postScale(ratio, ratio); 
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); 
        return newbmp; 
    }

    private static double getRatio(int srcWidth, int srcHeight, int maxWidth, int maxHeight) {
        double ratio = 0.0;
        double ratio_w = 0.0;
        double ratio_h = 0.0;
        if (srcWidth <= maxWidth && srcHeight <= maxHeight) {
            return 0.0;
        }

        ratio_w = (double) maxWidth / (double) srcWidth;
        ratio_h = (double) maxHeight / (double) srcHeight;

        if (ratio_w < ratio_h) {
            ratio = ratio_w;
        } else {
            ratio = ratio_h;
        }

        return ratio;
    }

	public static Bitmap rotateBitmap(File destFile, Bitmap bitmapOrg) {
		if (bitmapOrg == null) {
			return null;
		}
		Bitmap newBitmap = null;
		try {
			int rotateDegree = ImageUtil.getExifOrientation(destFile.getPath());
			if (rotateDegree != 0 && 0 == rotateDegree % 90) {
				Matrix m = new Matrix();
				m.setRotate(rotateDegree, bitmapOrg.getWidth() / 2f,
						bitmapOrg.getHeight() / 2f);
				newBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
						bitmapOrg.getWidth(), bitmapOrg.getHeight(), m, true);
			}
		} catch (Exception exception) {
			newBitmap = null;
		} catch (OutOfMemoryError e) {
			newBitmap = null;
		}
		if (newBitmap != null) {
			if (bitmapOrg != null && !bitmapOrg.isRecycled()
					&& !bitmapOrg.equals(newBitmap)) {
				bitmapOrg.recycle();
			}
			return newBitmap;
		} else {
			return bitmapOrg;
		}
	}
	
    public static int getExifOrientation(String filepath) {
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                // We only recognize a subset of orientation tag values.
                switch(orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
    
            }
        }
        return degree;
    }
	
	private static Bitmap scaleBitmap(Bitmap bitmapOrg, int max) {
		if (bitmapOrg == null) {
			return null;
		}
		Matrix m = new Matrix();
		int bitmapWidth = bitmapOrg.getWidth();
		int bitmapHeight = bitmapOrg.getHeight();
		float scale = max / (Math.max(bitmapWidth, bitmapHeight) * 1.0f);
		Bitmap newBitmap = null;
		try {
			if (scale != 1.0f && scale > 0) {
				m.postScale(scale, scale);
				newBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, bitmapWidth,bitmapHeight, m, true);
			}
		} catch(Exception e){
			e = null;
		} catch (OutOfMemoryError error) {
			error = null;
		}
		if (newBitmap != null) {
			if (bitmapOrg != null && !bitmapOrg.isRecycled()
					&& !bitmapOrg.equals(newBitmap)) {
				bitmapOrg.recycle();
			}
			return newBitmap;
		} else {
			return bitmapOrg;
		}
	}
}